package tp.pr4;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
//import tp.pr3.gui.Ventana;
import tp.pr4.cityLoader.CityLoaderFromTxtFile;
import tp.pr4.gui.MainWindow;
import tp.pr4.lang.ErrorMessages;
import tp.pr4.sound.Sound;
import tp.pr4.util.ArgumentParser;
import tp.pr4.util.FilterOutputStream;

public class Main {
	/**
	 * Inicializa los lugares y calles así como los parámetros para arrancar el robots
	 * @param args
	 * @throws IOException 
	 */
	
	
	public static void main (String args[]) {
		Sound.mute();
		Sound.gameMusicIntro.setVolumeGain(-10);
		Sound.gameMusicLoop.setVolumeGain(-10);
		
		String mainHelp = "Execute this assignment with these parameters:\nusage: tp.pr4.Main";
		ArgumentParser argPar = new ArgumentParser(mainHelp);
		
		//Initialize variables and configure the argument parser
		argPar.addCommand(argPar.new ArgumentParserOption(
				"h", new String[]{"help"}, false, false, false, 	"Shows this help message", null, false));
		argPar.addCommand(argPar.new ArgumentParserOption(
				"i", new String[]{"interface"}, true, true, true, 	"The type of interface: console or swing", "type", false));
		argPar.addCommand(argPar.new ArgumentParserOption (
				"m", new String[]{"map"}, true, true, true, 		"File with the description of the city", "mapfile", false));
		argPar.addCommand(argPar.new ArgumentParserOption (
				"s", new String[]{"sound"}, false, false, false, null, null, true));


		try {
			argPar.processArguments(args);
		} catch (IllegalArgumentException e) {
			//System.err.println(e.getMessage());
			//System.exit(1);
		}		
		
		//han pedido ayuda?
		if (argPar.hasCommandAppeared("h")) 
			Main.exitWithMessage(System.out, argPar.getHelp(), 0);
		//han puesto el mapa?
		if (!argPar.hasCommandAppeared("m")) 
			Main.exitWithMessage(System.err, "Map file not specified", 1);
		//han mandado la interfaz?
		if (!argPar.hasCommandAppeared("i"))
			Main.exitWithMessage(System.err, "Interface not specified", 1);
		//han pedido sonido?
		if (argPar.hasCommandAppeared("s"))
			Sound.unMute();
		
		//cargamos la interfaz
		boolean swing = false;
		if (argPar.hasCommandAppeared("i"))
			switch(argPar.getArg("i")) {
				case "swing":  swing = true; 
					System.setOut(new PrintStream(new FilterOutputStream(System.out,false)));
					System.setErr(new PrintStream(new FilterOutputStream(System.err,false))); 
					break;
				case "console": break;
				case "swingole": swing = true; break;
				default: Main.exitWithMessage(System.err, "Wrong type of interface", 1);
			}

		//cargamos el mapa
		City _places = null;		
		CityLoaderFromTxtFile loader = new CityLoaderFromTxtFile();
		String path = argPar.getArg("m");
		FileInputStream iFS;
		try {
			iFS = new FileInputStream(path);
			try {
				_places = loader.loadCity(iFS);
			} catch (IOException e) {
				Main.exitWithMessage(System.err, ErrorMessages.MAP_FILE_READING + argPar.getArg("m") + ErrorMessages.MAP_FILE_WRONG_SYNTAX, 2);
			}
		} catch (FileNotFoundException e1) {
			Main.exitWithMessage(System.err, ErrorMessages.MAP_FILE_READING + argPar.getArg("m") + ErrorMessages.MAP_FILE_NO_EXIST, 2);
		}
		
		//start the robot and all interfaces needed
		RobotEngine robotEngine = new AutoPlayer3( _places, loader.getInitialPlace(), Direction.NORTH);
		
		if (swing) 
			new MainWindow(robotEngine);
		else
			robotEngine.startEngine(); //si hemos cargado swing no aceptamos entradas de teclado por consola
		
	}
	
	/**
	 * Exits the application with the specified code, printing the message to the specified output, 
	 * @param output Where to print errMessage
	 * @param errMessage message to print
	 * @param errCode exit code of the application
	 */
	private static void exitWithMessage(PrintStream output, String errMessage, int errCode) {
		if (output != null && errMessage != null)
			output.println(errMessage);
		System.exit(errCode);
	}
}
